Fraction
	var
		numerator
		denominator

	New(top, bottom)
		src.numerator = top
		src.denominator = bottom

	proc
		Add(Fraction/F)
			if(isnum(F)) F = new(F, 1)
			var/Fraction/result = new(src.numerator * F.denominator + src.denominator * F.numerator,
										src.denominator * F.denominator)
			return result

		Copy()
			return new/Fraction(src.numerator, src.denominator)

		Equals(Fraction/F)
			return F.Value() == src.Value()

		Inverse()
			return new/Fraction(src.denominator, src.numerator)

		Multiply(Fraction/F)
			if(isnum(F)) F = new(F, 1)
			var/Fraction/result = src.Copy()
			result.numerator *= F.numerator
			result.denominator *= F.denominator
			return result

		Negate()
			var/Fraction/result = src.Copy()
			result.numerator *= -1
			return result

		Reduce()
			if(src.numerator == 0)
				new/Fraction(0, 1)
			// Remove decimals
			var
				n = src.numerator
				d = src.denominator
				places = 0
				ndec = n - Math.Floor(n)
				ddec = d - Math.Floor(d)
			if(ndec)
				places = Math.Floor(abs(log(10, ndec)))
			if(ddec)
				places = max(places, Math.Floor(abs(log(10, ddec))))
			if(places)
				n *= places * 10
				d *= places * 10
			var/gcd = Math.Gcd(n, d)
			return new/Fraction(n / gcd, d / gcd)

		Value()
			return src.numerator / src.denominator